package picounit.java;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestResult;
import picounit.java.collection.Filter;
import picounit.java.collection.Iterable;
import picounit.java.collection.List;
import picounit.java.type.Method;
import picounit.java.type.Type;

class Suite implements Test {
    public Suite(Type caller) {
        this.caller = caller;
    }

    public int countTestCases() {
        return size(testCases());
    }

    public void run(TestResult testResult) {
        for (Test testCase : testCases()) {
            testCase.run(testResult);
        }
    }

    private Iterable<Test> testCases() {
        List<Test> tests = new List<Test>();

        for (Type testType : testCaseTypes()) {
            for (Method testMethod : testType.publicMethods()) {
                tests.add(new PicoUnitTestCase(testMethod));
            }
        }

        return tests;
    }

    @SuppressWarnings("unused")
    private <T> int size(Iterable<T> iterable) {
        int count = 0;

        for (T item : iterable) {
            count++;
        }

        return count;
    }

    private Iterable<Type> testCaseTypes() {
        return caller.siblings().filter(new Filter<Type>() {
            public boolean passes(Type candidateTestType) {
                return new Type(TestCase.class).isAssignableFrom(candidateTestType);
            }
        });
    }

    private final Type caller;
}